exports.custom = function(player, req, resp, onHandled){
    var user = player.user;
    do {
        var name = req.args.name;
        var value = req.args.value;
        var operation = req.args.operation;

        var names = name.split(".");
        if (names.length < 1) {
            resp.code = 1; resp.desc = 'custom name invalid'; break;
        }

        if (!isNaN(value)) {
            value = +value;
        } else {
            try {
                value = JSON.parse(value); 
            } catch (e) {
                resp.code = 1; resp.desc = e.message; break;
            }
        }

        switch (operation) {
            case 'set': 
                var key = names[names.length-1];
                var obj = getObjectNamesParent(user, names);

                if (!obj) {
                    resp.code = 1; resp.desc = 'custom set name invalid'; break;
                }

                obj[key] = value;
                player.save();
                break;
            case 'gset':
                var key = names[names.length-1];
                var obj = getObjectNamesParent(global, names);

                if (!obj) {
                    resp.code = 1; resp.desc = 'custom gset name invalid'; break;
                }

                obj[key] = value;
                break;
            case 'log':
                var obj = getObjectNamesValue(user, names);
                ERROR(util.format('%j', obj));
                break;
            case 'glog':
                var obj = getObjectNamesValue(global, names);
                ERROR(util.format('%j', obj));
                break;
            case 'fun': 
                var handler = getObjectNamesValue(logic, names);
                if (!handler) {
                    resp.code = 1; resp.desc = 'custom function name invalid'; break;
                }
                
                for (var k in value) {
                    req.args[k] = value[k];
                }
                handler(player, req, resp, function() {
                    onHandled();
                });
                return;
                break;
            default:
                resp.code = 1; resp.desc = 'custom operation invalid'; break;
                break;
        }
    } while (false);

    onHandled();
}
